package com.danco.training.zaneuskaya.controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.swing.text.SimpleAttributeSet;

import com.danco.training.zaneuskaya.api.BookController;
import com.danco.training.zaneuskaya.communication.MessageAnalyzer;
import com.danco.training.zaneuskaya.domain.Book;
import com.danco.training.zaneuskaya.view.IOUtil;

public class BookControllerImpl implements BookController {

	private static final String UPDATE_ENTITY = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;updateEntity";

	private static final String ENTER_RECEIVING_DATE = "Enter receiving date";

	private static final String GET_LIST_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getList";

	private static final String GET_BOOKS_SORTED_BY_ALPHABET_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getBooksSortedByAlphabet";

	private static final String GET_BOOKS_SORTED_BY_PUBLICATION_DATE_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getBooksSortedByPublicationDate";

	private static final String GET_BOOKS_SORTED_BY_PRICE_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getBooksSortedByPrice";

	private static final String GET_AVAILABLE_BOOKS_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getAvailableBooks";

	private static final String GET_NOT_AVAILABLE_BOOKS_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getNotAvailableBooks";

	private static final String GET_UNSOLD_BOOKS_SORTED_BY_RECEIPT_DATE_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getUnsoldBooksSortedByReceiptDate";

	private static final String GET_UNSOLD_BOOKS_SORTED_BY_PRICE_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getUnsoldBooksSortedByPrice";

	private static final String GET_BY_ID_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;getById";

	private static final String REMOVE_ENTITY_BY_ID_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;removeEntityById";

	private static final String SAVE_ENTITY_LIST_TO_FILE_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;saveEntityListToFile";

	private static final String READ_ENTITY_LIST_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;readEntityList";

	private static final String ADD_ENTITY_SERVICE = "com.danco.training.zaneuskaya.service.impl.BookServiceImpl;addEntity";

	private static final String READ_BOOK_LIST_FROM_FILE_MESSAGE = "Enter file to read book list";

	private static final String SAVED_BY_DEFAULT_IN = "Saved by default in ";

	private static final String FILE_TO_SAVE_DESTINATION = "d:\\file3.csv";

	private static final String SAVE_BOOK_LIST_TO_FILE_MESSAGE = "Enter directory and file name :";

	private static final String DELETE_BOOK_MESSAGE = "Enter book Id to delete:";

	private static final String ENTER_NEW_TITLE = "Enter new title:";

	private static final String UPDATE_BOOK_MESSAGE = "Enter book Id to modify: ";

	private static final String BOOK_NOT_EXISTED = "Book not existed";

	private static final String PRINT_BOOK_INFO_MESSAGE = "Enter book's to show Id";

	private static final String ENTER_PUBLICATION_DATE = "Enter publication date yyyy-[m]m-[d]d";

	private static final String ENTER_BOOK_AUTHOR = "Enter book author:";

	private static final String ENTER_BOOK_TITLE_FOR_CREATION = "Enter book title for creation:";

	private static final String PRINT_UNSOLD_BOOKS_SORTED_BY_PRICE = "Unsold Books in Bookstorage  sorted by price";

	private static final String PRINT_UNSOLD_BOOKS_SORTED_BY_RECEIPT_DATE_MESSAGE = "Books in Bookstorage unsold for some months sorted by receipt date";

	private static final String PRINT_NOT_AVAILABLE_BOOKS_MESSAGE = "Not available Books in Bookstorage ";

	private static final String PRINT_AVAILABLE_BOOKS_MESSAGE = "Available Books in Bookstorage ";

	private static final String PRINT_BOOK_LIST_SORTED_BY_PRICE_MESSAGE = "Books in Bookstorage sorted by price";

	private static final String PRINT_BOOK_LIST_SORTED_BY_PUBLICATION_DATE_MESSAGE = "Books in Bookstorage sorted by publication date";

	private static final String PRINT_BOOK_LIST_SORTED_BY_ALPHABET_MESSAGE = "Books in Bookstorage sorted by alphabet";

	private static final String PRINT_BOOK_LIST_MESSAGE = "Books in Bookstorage";
	
	public SimpleDateFormat pattern = new SimpleDateFormat("dd-MM-yyyy");

	@SuppressWarnings("unchecked")
	public synchronized void printBookList() {
		IOUtil.write(PRINT_BOOK_LIST_MESSAGE);

		List<Book> books;

		try {
			books = (List<Book>) MessageAnalyzer.executeMethod(
					GET_LIST_SERVICE, null);
			for (Book book : books) {
				IOUtil.write(bookInfo(book.getId()));
			}
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printBookListSortedByAlphabet() {
		IOUtil.write(PRINT_BOOK_LIST_SORTED_BY_ALPHABET_MESSAGE);

		List<Book> sortedBooks;
		try {

			sortedBooks = (List<Book>) MessageAnalyzer.executeMethod(
					GET_BOOKS_SORTED_BY_ALPHABET_SERVICE, new Object[] {});
			for (Book book : sortedBooks) {
				IOUtil.write(bookInfo(book.getId()));
			}
		} catch (IOException e) {
			IOUtil.write(e.getMessage());

		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printBookListSortedByPublicationDate() {
		IOUtil.write(PRINT_BOOK_LIST_SORTED_BY_PUBLICATION_DATE_MESSAGE);

		List<Book> sortedBooks;
		try {

			sortedBooks = (List<Book>) MessageAnalyzer.executeMethod(
					GET_BOOKS_SORTED_BY_PUBLICATION_DATE_SERVICE,
					new Object[] {});
			for (Book book : sortedBooks) {
				IOUtil.write(bookInfo(book.getId()));
			}
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printBookListSortedByPrice() {
		IOUtil.write(PRINT_BOOK_LIST_SORTED_BY_PRICE_MESSAGE);

		List<Book> sortedBooks = null;

		try {

			sortedBooks = (List<Book>) MessageAnalyzer.executeMethod(
					GET_BOOKS_SORTED_BY_PRICE_SERVICE, new Object[] {});
			for (Book book : sortedBooks) {
				IOUtil.write(bookInfo(book.getId()));
			}

		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printAvailableBooks() {
		IOUtil.write(PRINT_AVAILABLE_BOOKS_MESSAGE);
		List<Book> books;
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod(
					GET_AVAILABLE_BOOKS_SERVICE, null);
			for (Book book : books) {
				IOUtil.write(bookInfo(book.getId()));
			}

		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printNotAvailableBooks() {
		IOUtil.write(PRINT_NOT_AVAILABLE_BOOKS_MESSAGE);
		List<Book> books;
		try {
			books = (List<Book>) MessageAnalyzer.executeMethod(
					GET_NOT_AVAILABLE_BOOKS_SERVICE, null);
			for (Book book : books) {
				IOUtil.write(bookInfo(book.getId()));
			}
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printUnsoldBooksSortedByReceiptDate() {
		IOUtil.write(PRINT_UNSOLD_BOOKS_SORTED_BY_RECEIPT_DATE_MESSAGE);

		List<Book> sortedBooks;
		try {

			sortedBooks = (List<Book>) MessageAnalyzer.executeMethod(
					GET_UNSOLD_BOOKS_SORTED_BY_RECEIPT_DATE_SERVICE,
					new Object[] {});
			for (Book book : sortedBooks) {
				IOUtil.write(bookInfo(book.getId()));
			}

		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printUnsoldBooksSortedByPrice() {
		IOUtil.write(PRINT_UNSOLD_BOOKS_SORTED_BY_PRICE);

		List<Book> sortedBooks;
		try {

			sortedBooks = (List<Book>) MessageAnalyzer.executeMethod(
					GET_UNSOLD_BOOKS_SORTED_BY_PRICE_SERVICE, new Object[] {});
			for (Book book : sortedBooks) {
				IOUtil.write(bookInfo(book.getId()));
			}

		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void createBook() {

		IOUtil.write(ENTER_BOOK_TITLE_FOR_CREATION);
		String title = IOUtil.read();
		IOUtil.write(ENTER_BOOK_AUTHOR);
		String author = IOUtil.read();
		IOUtil.write(ENTER_PUBLICATION_DATE);
		Date date = IOUtil.readDate();
		IOUtil.write(ENTER_RECEIVING_DATE);
		Date date1 = IOUtil.readDate();
		IOUtil.write("Enter price");
		double price = IOUtil.readDouble();
		IOUtil.write("Enter quantity");
		int quantity = IOUtil.readInt();
		boolean available = false;
		if (quantity > 0) {
			available = true;
		}

		Book book = new Book(title, author, date, price, available, quantity,
				date1);
		try {

			MessageAnalyzer.executeMethod(ADD_ENTITY_SERVICE,
					new Object[] { book });

		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void printBookInfo() {

		IOUtil.write(PRINT_BOOK_INFO_MESSAGE);
		int id = IOUtil.readInt();

		System.out.println(bookInfo(id));

	}

	public String bookInfo(int id) {

		StringBuffer str = new StringBuffer();
		Book book = null;
		try {
			book = (Book) MessageAnalyzer.executeMethod(GET_BY_ID_SERVICE,
					new Object[] { id });
			str.append(book.getId());
			str.append("  ");
			str.append(book.getTitle());
			str.append("   ");
			str.append(book.getAuthor());
			str.append("   ");
			str.append(pattern.format(book.getPublicationDate()));
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

		return str.toString();
	}

	public void updateBook() {

		Book book = null;

		while (book == null) {

			IOUtil.write(UPDATE_BOOK_MESSAGE);
			int id = IOUtil.readInt();
			try {
				book = (Book) MessageAnalyzer.executeMethod(GET_BY_ID_SERVICE,
						new Object[] { id });

				IOUtil.write(ENTER_NEW_TITLE);
				String t = IOUtil.read();
				IOUtil.write(ENTER_BOOK_AUTHOR);
				String author = IOUtil.read();
				IOUtil.write(ENTER_PUBLICATION_DATE);
				Date date = IOUtil.readDate();
				IOUtil.write(ENTER_RECEIVING_DATE);
				Date date1 = IOUtil.readDate();
				IOUtil.write("Enter price");
				double price = IOUtil.readDouble();
				IOUtil.write("Enter quantity");
				int quantity = IOUtil.readInt();
				boolean available = false;
				if (quantity > 0) {
					available = true;
				}
				if (!author.isEmpty()) {
					book.setAuthor(author);
				}
				if (!t.isEmpty()) {
					book.setTitle(t);
				}
				if (date != null) {
					book.setPublicationDate(date);
				}
				book.setAvailable(available);
				if (date1 != null) {
					book.setReceiptDate(date1);
				}

				book.setPrice(price);

				book.setQuantity(quantity);
				try {
					MessageAnalyzer.executeMethod(UPDATE_ENTITY,
							new Object[] { book });
				} catch (IOException e) {
					IOUtil.write(e.getMessage());
				} catch (ClassNotFoundException e) {
					IOUtil.write(e.getMessage());
				}

				IOUtil.write(bookInfo(book.getId()));

			} catch (ClassNotFoundException | IOException e) {
				IOUtil.write(e.getMessage());
			}
		}
	}

	public void deleteBook() {

		IOUtil.write(DELETE_BOOK_MESSAGE);
		int id = IOUtil.readInt();
		Book book = null;
		try {
			book = (Book) MessageAnalyzer.executeMethod(GET_BY_ID_SERVICE,
					new Object[] { id });
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}
		while (book == null) {
			IOUtil.write(BOOK_NOT_EXISTED);
			IOUtil.write(DELETE_BOOK_MESSAGE);
			id = IOUtil.readInt();
		}
		try {
			MessageAnalyzer.executeMethod(REMOVE_ENTITY_BY_ID_SERVICE,
					new Object[] { id });
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void saveBookListToFile() {

		IOUtil.write(SAVE_BOOK_LIST_TO_FILE_MESSAGE);
		String file = IOUtil.read();
		if (file.isEmpty()) {
			file = FILE_TO_SAVE_DESTINATION;
			IOUtil.write(SAVED_BY_DEFAULT_IN + FILE_TO_SAVE_DESTINATION);

		}
		try {
			MessageAnalyzer.executeMethod(SAVE_ENTITY_LIST_TO_FILE_SERVICE,
					new Object[] { file });
		} catch (IOException e) {
			IOUtil.write(e.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

	public void readBookListFromFile() {

		IOUtil.write(READ_BOOK_LIST_FROM_FILE_MESSAGE);
		String file = IOUtil.read();
		if (file.isEmpty()) {
			file = FILE_TO_SAVE_DESTINATION;

		}

		try {
			List<Book> books = (List<Book>) MessageAnalyzer.executeMethod(
					READ_ENTITY_LIST_SERVICE, new Object[] { file });
			for (Book book : books) {

				MessageAnalyzer.executeMethod(ADD_ENTITY_SERVICE,
						new Object[] { book });
			}
		} catch (IOException e1) {
			IOUtil.write(e1.getMessage());
		} catch (ClassNotFoundException e) {
			IOUtil.write(e.getMessage());
		}

	}

}
